#include <iostream>
using namespace std;

// 复数类
class Complex{
    private:
        int real; // 实部
        int vir;  // 虚部
    public:
        Complex():real(0), vir(0){}
        Complex(int r, int v):real(r), vir(v){}
        ~Complex(){}
        // 算数运算符 + 的重载
        Complex operator+(const Complex &R)const{
            Complex temp;
            temp.real = this->real + R.real;
            temp.vir = vir + R.vir;
            return temp;
        }
        // 算术运算 - 重载
        friend Complex operator-(const Complex &L, const Complex &R);
        // 关系运算符 > 重载
        bool operator>(const Complex &R)const{
            // 我们自定义的规则 实>实 && 虚>虚 
            if(real > R.real && vir > R.vir){
                return true;
            }else{
                return false;
            }
        }
        // 关系运算符 == 重载
        friend bool operator==(const Complex &L, const Complex &R);
        // 赋值运算符 = 的重载 : 就是拷贝赋值函数
        Complex &operator=(const Complex &R){
            if(this != &R){
                real = R.real;
                vir = R.vir;
            }
            return *this;
        }
        // 赋值运算符 += 的重载
        friend Complex &operator+=(Complex &L, const Complex &R);
        // 单目运算符 -(负) 的重载
        const Complex operator-(void)const{
            Complex temp;
            temp.real = -real;
            temp.vir = -vir;
            return temp;
        }
        // 前缀自增运算符 ++ 的重载
        Complex &operator++(void){
            real += 1;
            vir += 1;
            return *this;
        }
        // 后缀自增运算符 ++ 的重载  (我们把它实现成全局函数版了 这里就不用了)
        // const Complex operator++(int){
        //     Complex temp(*this);
        //     real += 1;
        //     vir += 1;
        //     return temp;
        // }
        friend const Complex operator++(Complex &O, int);
        // 插入运算符的重载
        friend ostream &operator<<(ostream &x, const Complex &O);
        // 提取运算符的重载
        friend istream &operator>>(istream &x, Complex &O);
};
// 全局函数版 不能再实现 + 的重载了  否则调用会有歧义
// 算术运算 - 重载
Complex operator-(const Complex &L, const Complex &R){
    Complex temp;
    temp.real = L.real - R.real;
    temp.vir = L.vir - R.vir;
    return temp;
}

// 关系运算符 == 重载
bool operator==(const Complex &L, const Complex &R){
    if(L.real == R.real && L.vir == R.vir){
        return true;
    }else{
        return false;
    }
}

// 赋值运算符 += 的重载
Complex &operator+=(Complex &L, const Complex &R){
    if(&L != &R){
        L.real += R.real;
        L.vir += R.vir;
    }
    return L;
}

//后缀自增运算符 ++ 的重载
const Complex operator++(Complex &O, int){
    Complex temp(O);
    O.real += 1;
    O.vir += 1;
    return temp;
}

// 插入运算符的重载
ostream &operator<<(ostream &x, const Complex &O){
    if(O.vir >= 0){
        // 这里使用cout输出也可以 使用x输出也可以
        // 因为 x 引用的目标就是 cout  
        // 我们使用 x 更合理一些
        x << O.real << "+" << O.vir << "i";
    }else{
        x << O.real  << O.vir << "i";
    }
    return x; // 返回自身的引用是为了级联使用的场景
}

// 提取运算符的重载
istream &operator>>(istream &x, Complex &O){
    // 此处形参的 x 引用的目标就是 cin
    x >> O.real >> O.vir;
    return x; // 返回自身的引用是为了级联使用的场景
}

int main(int argc, const char *argv[]){
    Complex c1(5, 6);
    cout << c1 << endl; // 5+6i
    Complex c2(1, 2);
    cout << c2 << endl; // 1+2i

    Complex c3;
    c3 = c1+c2;
    cout << c3 << endl; // 6+8i

    Complex c4 = c1 - c2;
    cout << c4 << endl; // 4+4i

    if(c1 > c2){
        cout << "yes" << endl; // yes
    }else{
        cout << "no" << endl;
    }

    Complex c5(5, 6);
    if(c1 == c5){
        cout << "==" << endl; // ==
    }else{
        cout << "!=" << endl;
    }

    c2 += c1;
    cout << c1 << endl; // 5+6i
    cout << c2 << endl; // 6+8i

    c1 = -c2;
    cout << c1 << endl; // -6-8i
    cout << c2 << endl; // 6+8i

    Complex c6(2, 3);
    cout << c6 << endl; // 2+3i
    Complex c7;
    c7 = ++++++c6;
    cout << c6 << endl; // 5+6i
    cout << c7 << endl; // 5+6i

    Complex c8(2, 3);
    cout << c8 << endl; // 2+3i
    Complex c9;
    c9 = c8++;
    cout << c8 << endl; // 3+4i
    cout << c9 << endl; // 2+3i

    cout << "-------------------" << endl;
    // 验证级联使用
    cin >> c8 >> c9;
    cout << c8 << "  " << c9 << endl;

    return 0;
}